#ifndef __CHARGE_OS_H_
#define __CHARGE_OS_H_

#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdarg.h>

#include "charge_user.h"

#ifdef __cplusplus
extern "C"{
#endif

//根据具体情况自己做修改，如果平台支持，需要修改宏包含的内容
#define LINUX                   1
#define FREERTOS                2
#define OTHRER_OS               3
#define NO_OS                   4

#define SUPPORT_SYSTEM_OS       LINUX

typedef unsigned int os_timestamp_t;

void log_output(uint8_t level, char *format, ...);

#if LOG_OUTPUT_LVL >= LOG_LVL_ERROR
    #define log_error(tag, ...) \
            log_output(LOG_LVL_ERROR, tag, ##__VA_ARGS__)
#else
    #define log_error(tag, ...)
#endif /* LOG_OUTPUT_LVL >= LOG_LVL_ERROR */

#if LOG_OUTPUT_LVL >= LOG_LVL_WARN
    #define log_warn(tag, ...) \
            log_output(LOG_LVL_WARN, tag, ##__VA_ARGS__)
#else
    #define log_warn(tag, ...)
#endif /* LOG_OUTPUT_LVL >= LOG_LVL_WARN */

#if LOG_OUTPUT_LVL >= LOG_LVL_DEBUG
    #define log_debug(tag, ...) \
            log_output(LOG_LVL_DEBUG, tag, ##__VA_ARGS__)
#else
    #define log_debug(tag, ...)
#endif /* LOG_OUTPUT_LVL >= LOG_LVL_DEBUG */

#define log_printf(tag, ...) \
        log_output(0xFF, tag, ##__VA_ARGS__)

#if SUPPORT_SYSTEM_OS == LINUX

typedef pthread_mutex_t     os_mutex_t;         //互斥信号结构
typedef pthread_t           os_thread_t;        //任务控制块

#elif SUPPORT_SYSTEM_OS == FREERTOS

#include "FreeRTOS.h"
#include "task.h"
#include "semphr.h"
#include "FreeRTOSConfig.h"
typedef xSemaphoreHandle    os_mutex_t;         //互斥信号结构
typedef xTaskHandle         os_thread_t;        //任务控制块

#elif SUPPORT_SYSTEM_OS == NO_OS

#include "charge_timer.h"
typedef int                 os_mutex_t;         //互斥信号结构
typedef charge_timer        os_thread_t;        //任务控制块

#else

typedef int                 os_mutex_t;         //互斥信号结构
typedef int                 os_thread_t;        //任务控制块

#endif

#if SUPPORT_SYSTEM_OS == NO_OS

//任务运行周期，以下按照1s / 1000tisk 计算
typedef enum
{
    os_priority_Idle          = 0,           // 不使用
    os_priority_Low           = 1000,        // 1S
    os_priority_BelowNormal   = 500,         // 500ms
    os_priority_Normal        = 100,         // 100ms
    os_priority_AboveNormal   = 50,          // 50ms
    os_priority_High          = 10,          // 10ms
    os_priority_Realtime      = 1,           // 1ms
} os_task_priority_t;

#else

typedef enum
{
    os_priority_Idle          = 0,           // idle (lowest)
    os_priority_Low           = 1,           // low
    os_priority_BelowNormal   = 2,           // below normal
    os_priority_Normal        = 3,           // normal (default)
    os_priority_AboveNormal   = 4,           // above normal
    os_priority_High          = 5,           // high
    os_priority_Realtime      = 6,           // realtime (highest)
} os_task_priority_t;

#endif

void os_ts_to_time(uint32_t tick, struct os_time* ot);
void os_server_ts_to_time(uint32_t tick, struct os_time *ot);
os_timestamp_t os_time_to_ts(struct os_time ot);

/*****************************************************************************
函数名称 : os_get_time
功能描述 : 获取当前系统时间
传入参数 : 无
传出参数 : 无
返回参数 : 实时时间戳
*****************************************************************************/
uint32_t os_get_time(void);
/*****************************************************************************
函数名称 : os_sleep_ms
功能描述 : 系统/任务睡眠
传入参数 : ms : 睡眠时长，单位毫秒
传出参数 : 无
返回参数 : 无
*****************************************************************************/
void os_sleep_ms(uint32_t ms);
/*****************************************************************************
函数名称 : os_srandom
功能描述 : 设置随机数种子
传入参数 : seed : 随机数种子
传出参数 : 无
返回参数 : 无
*****************************************************************************/
void os_srandom(uint32_t seed);
/*****************************************************************************
函数名称 : os_random
功能描述 : 获取一个随机数
传入参数 : 无
传出参数 : 无
返回参数 : 随机数
*****************************************************************************/
uint32_t os_random(void);
/*****************************************************************************
函数名称 : os_print
功能描述 : 日志输出
传入参数 : str : 日志的字符串内容
传出参数 : 无
返回参数 :  无
*****************************************************************************/
void os_print(const char *str);
/*****************************************************************************
函数名称 : os_persist_data_write
功能描述 : 持久化保存数据
传入参数 : data : 保存的数据
传入参数   data_len : 数据长度
传出参数 : 无
返回参数 : 0 : 成功
           -1 : 失败
*****************************************************************************/
int32_t os_persist_data_write(const void *data, uint32_t data_len);
/*****************************************************************************
函数名称 : os_persist_data_read
功能描述 : 读取持久化数据
传入参数 : data_len : 读取长度
传出参数 : data : 保存数据的缓冲区
返回参数 : 0 : 成功
           -1 : 失败
*****************************************************************************/
int32_t os_persist_data_read(void *data, uint32_t data_len);

/*****************************************************************************
函数名称 : os_create_download_file
功能描述 : 创建下载的文件
传入参数 : file_name : 文件名字
返回参数 : 0 : 成功
           -1 : 失败
*****************************************************************************/
int32_t os_create_download_file(char *file_name);

/*****************************************************************************
函数名称 : os_write_download_file_data
功能描述 : 写入下载的数据到文件
传入参数 : file_name : 文件名字
传入参数 : offset : 偏移地址
传入参数 : data : 保存的数据
传入参数   data_len : 数据长度
返回参数 : 0 : 成功
           -1 : 失败
*****************************************************************************/
int32_t os_write_download_file_data(char *file_name, uint32_t offset, void *data, uint16_t data_len);

/*****************************************************************************
函数名称 : os_download_file_done
功能描述 : 下载完成
传入参数 : file_name : 文件名字
传入参数 : state : 是否成功  0：成功 1：失败
返回参数 : 0 : 成功
           -1 : 失败
*****************************************************************************/
int32_t os_download_file_done(char *file_name, uint8_t state);

#define CHARGE_THREAD_STACK_SIZE    256
/*****************************************************************************
函数名称 : os_thread_create
功能描述 : 创建线程/任务
传入参数 : name          : 任务名称
          thread        : 任务句柄指针
          start_routine : 任务函数，通常是一个死循环
          arg           : 传递给任务函数的参数  
          prio          : 任务的优先级
          stack_size    : 任务栈空间大小，单位字节
传出参数 : 无
返回参数 : 0 : 成功
         -1 : 失败
*****************************************************************************/
int32_t os_thread_create(const char *name, os_thread_t *thread, void *(*work_routine)(void *arg), \
                            void *par, os_task_priority_t prio, uint32_t stack_size) ;
/*****************************************************************************
函数名称 : os_mutex_create
功能描述 : 创建互斥锁
传入参数 : mutex : 互斥锁句柄指针
传出参数 : 无
返回参数 : 0 : 成功
         -1 : 失败
*****************************************************************************/
int32_t os_mutex_create(os_mutex_t* mutex);
/*****************************************************************************
函数名称 : os_mutex_destroy
功能描述 : 删除互斥锁
传入参数 : mutex : 互斥锁句柄指针
传出参数 : 无
返回参数 : 0 : 成功
         -1 : 失败
*****************************************************************************/
int32_t os_mutex_destroy(os_mutex_t* mutex);
/*****************************************************************************
函数名称 : os_mutex_lock
功能描述 : 获取互斥锁
传入参数 : mutex : 互斥锁句柄指针
          timeout_ms : 超时时长，单位毫秒
传出参数 : 无
返回参数 : 0 : 成功
         -1 : 失败
*****************************************************************************/
int32_t os_mutex_lock(os_mutex_t *mutex ,uint32_t timeout_ms);
/*****************************************************************************
函数名称 : os_mutex_unlock
功能描述 : 释放互斥锁
传入参数 : mutex : 互斥锁句柄指针
传出参数 : 无
返回参数 :  0 : 成功
          -1 : 失败
*****************************************************************************/
int32_t os_mutex_unlock(os_mutex_t *mutex);

#define OS_MUTEX_INIT(mtx_ptr)              (os_mutex_create((mtx_ptr)))
#define OS_MUTEX_LOCK(mtx_ptr, time_ms)     (os_mutex_lock((mtx_ptr), time_ms))
#define OS_MUTEX_UNLOCK(mtx_ptr)            (os_mutex_unlock((mtx_ptr)))
#define OS_MUTEX_DESTORY(mtx_ptr)           (os_mutex_destroy((mtx_ptr)))

typedef int32_t os_socket_t;
/*****************************************************************************
函数名称 : _tcp_open
功能描述 : 建立tcp连接
传入参数 : host : 服务器地址
                         port : 服务器端口
传出参数 : 无
返回参数 : >0 : 建立连接成功，返回套接字
           -1 : 失败
*****************************************************************************/
os_socket_t _tcp_open(const int8_t *host, uint16_t port);
/*****************************************************************************
函数名称 : _tcp_close
功能描述 : 关闭tcp连接
传入参数 : fd  : 套接字
传出参数 : 无
返回参数 : 0 : 成功
           -1 : 失败
*****************************************************************************/
int32_t _tcp_close(os_socket_t fd);
/*****************************************************************************
函数名称 : _tcp_write
功能描述 : 发送tcp数据
传入参数 : fd  : 套接字
                        buf : 期望发送的数据
                        len : 期望发送数据的长度
                        timeout_ms : 超时时长，单位毫秒
传出参数 : 无
返回参数 : >0 : 发送成功，返回发送成功的字节数
                        =0 : 发送超时
                        <0 : 发送失败，连接发生错误，应关闭连接
*****************************************************************************/
int32_t _tcp_write(os_socket_t fd, const int8_t *buf, uint32_t len, uint32_t timeout_ms);
/*****************************************************************************
函数名称 : _tcp_read
功能描述 : 读取tcp数据
传入参数 : fd  : 套接字
                        len : 期望接收的最大长度
                        timeout_ms : 超时时长，单位毫秒
传出参数 : buf : 接收数据缓冲区
返回参数 : >0 : 读取成功，返回读到的字节数
                        =0 : 读取超时，连接上没有数据
                        <0 : 读取失败，连接发生错误，应关闭连接
*****************************************************************************/
int32_t _tcp_read(os_socket_t fd, int8_t *buf, uint32_t len, uint32_t timeout_ms);

#ifdef __cplusplus
}
#endif

#endif
